package com.fw.ui.view.event;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.fw.service.bean.ErrorBean;
import com.fw.ui.bao.MessageBAO;
import com.vaadin.event.ShortcutListener;
import com.vaadin.server.Page;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Notification;

public abstract class AbstractButtonClickListener extends AbstractListener implements ClickListener {

    private static final long serialVersionUID = 9029495651958529920L;

    private ShortcutListener shortcutListener;
    private boolean autoEnabled = true;

    @Autowired
    private MessageBAO messageBAO;

    @Override
    public void buttonClick(ClickEvent event) {
	Logger log = LoggerFactory.getLogger(this.getClass());
	try {
	    if (this.filter()) {
		if (autoEnabled) {
		    event.getButton().setEnabled(true);
		}
		return;
	    }
	    if (this.validate(event)) {
		log.info("VALIDATE EVENT CLICK LISTENER [RESULT:TRUE]");
		log.info("EXECUTE EVENT CLICK LISTENER START");
		Map<String, Object> map = this.click(event);
		this.notification(map);
		log.info("EXECUTE EVENT CLICK LISTENER FINISH");
	    } else {
		log.info("VALIDATE EVENT CLICK LISTENER [RESULT:FALSE]");
	    }
	} catch (TimeoutException e) {
	    log.error("EVENT CLICK LISTENER ERROR [" + e.getMessage() + "]");
	    e.printStackTrace();
	    String msg = this.messageBAO.getMessage("message.error.timeout");
	    Notification notification = new Notification("Warning", msg, Notification.Type.WARNING_MESSAGE, true);
	    notification.setDelayMsec(1000);
	    notification.show(Page.getCurrent());
	} catch (Exception e) {
	    log.error("EVENT CLICK LISTENER ERROR [" + e.getMessage() + "]");
	    e.printStackTrace();
	    String msg = this.messageBAO.getMessage("message.error.common");
	    Notification notification = new Notification("Warning", msg, Notification.Type.WARNING_MESSAGE, true);
	    notification.setDelayMsec(1000);
	    notification.show(Page.getCurrent());
	}
	if (autoEnabled) {
	    event.getButton().setEnabled(true);
	}
    }

    public abstract boolean validate(ClickEvent event) throws Exception;

    public abstract Map<String, Object> click(ClickEvent event) throws Exception;

    public ShortcutListener getShortcutListener() {
	return shortcutListener;
    }

    public void setShortcutListener(ShortcutListener shortcutListener) {
	this.shortcutListener = shortcutListener;
    }

    public boolean isAutoEnabled() {
	return autoEnabled;
    }

    public void setAutoEnabled(boolean autoEnabled) {
	this.autoEnabled = autoEnabled;
    }

    @SuppressWarnings("unchecked")
    public void notification(Map<String, Object> map){
	if (map != null && !map.isEmpty()) {
	    Object objectInfoMsg = map.get(MessageBAO.MESSAGE_INFO_TYPE);
	    Object objectWarnMsg = map.get(MessageBAO.MESSAGE_WARNING_TYPE);
	    Object objectErrorMsg = map.get(MessageBAO.MESSAGE_ERROR_TYPE);
	    if (objectErrorMsg != null) {
		String key = (String) objectErrorMsg;
		String msg = messageBAO.getMessage(key);
		if (msg == null) {
		    msg = key;
		}
		Notification notification = new Notification("Error", msg, Notification.Type.WARNING_MESSAGE, true);
		notification.setDelayMsec(1000);
		notification.show(Page.getCurrent());
	    } else if (objectWarnMsg != null) {
		String msg = "";
		if (objectWarnMsg instanceof List) {
		    List<ErrorBean> errorBeans = (List<ErrorBean>) objectWarnMsg;
		    if (errorBeans != null && !errorBeans.isEmpty()) {
			for (ErrorBean errorBean : errorBeans) {
			    msg += messageBAO.getMessageWithParams(errorBean.getErrorCode(), errorBean.getErrorParameters())
				    + " <br/>";
			}
		    }
		} else if (objectWarnMsg instanceof String) {
		    String key = (String) objectWarnMsg;
		    msg = messageBAO.getMessage(key);
		    if (msg == null) {
			msg = key;
		    }
		}
		Notification notification = new Notification("Warning", msg, Notification.Type.WARNING_MESSAGE, true);
		notification.setDelayMsec(1000);
		notification.show(Page.getCurrent());
	    } else if (objectInfoMsg != null) {
		String key = (String) objectInfoMsg;
		String msg = messageBAO.getMessage(key);
		if (msg == null) {
		    msg = key;
		}
		Notification notification = new Notification("Info", msg, Notification.Type.HUMANIZED_MESSAGE, true);
		notification.setDelayMsec(1000);
		notification.show(Page.getCurrent());
	    }
	}
    }
}
